﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.VisualStudio.TestTools.UnitTesting
{
	internal static class Should
	{

		internal static ICollection ToCollection<T>( this IEnumerable<T> items )
		{
			System.Collections.ObjectModel.Collection<T> coll = new System.Collections.ObjectModel.Collection<T>();

			items.Each( i => coll.Add( i ) );
			return coll;
		}

		public static void BeEquivalent<TElement>( IEnumerable<TElement> elements, IEnumerable<TElement> set )
		{
			if ( elements.All( x => set.Contains( x ) )
				&& set.All( x => elements.Contains( x ) ) )
			{
			}
			else
			{
				Assert.Fail();
			}
		}

        public static void BeEquivalent<TElement>( IEnumerable<TElement> elements, IEnumerable<TElement> set, Func<TElement, TElement, bool> comparer )
        {
            if ( !elements.All( x1 => set.Any( x2 => comparer( x1, x2 ) ) )
                || !set.All( x2 => elements.Any( x1 => comparer( x2, x1 ) ) ) )
            {
                Assert.Fail();
            }
        }

		public static void ThrowWithMessage( string msg, Action method )
		{
			bool fail = true;

			try
			{
				method();
			}
			catch ( Exception ex )
			{
				fail = !String.Equals( msg, ex.Message );
			}
			finally
			{
				if ( fail )
					Assert.Fail( "A exceção esperada com a mensagem \"{0}\" não foi lançada.", msg );
			}
		}

		public static void Throw<TExcetion>( Action method )
			where TExcetion : Exception
		{
			bool fail = true;

			try
			{
				method();
			}
			catch ( Exception ex )
			{
				fail = !( ex is TExcetion );
			}
			finally
			{
				if ( fail )
					Assert.Fail( "A exceção do tipo \"{0}\" não foi lançada.", typeof( TExcetion ).FullName );
			}
		}
	}
}
